
#include <BFont>
#include <BPainter>
#include <BMouseEvent>
#include <BChangeEvent>

#include <BMenuBar>
#include "member_BMenuBar.h"

using namespace BWE;

#define member					(*(member_BMenuBar*)_ptr)
#define member_allocate()		_ptr = new member_BMenuBar(this)
#define member_release()		delete (member_BMenuBar*)_ptr

BMenuBar::BMenuBar(BWidget* parent) : BWidget(parent)
{
	member_allocate();
}
BMenuBar::~BMenuBar()
{
	member_release();
}

void BMenuBar::addMenu(BMenu* menu)
{
	if (!this->contain(menu))
	{
		this->addChild(menu);
		menu->hide();
		member.items.append(menu);
		member.dirty = true;
		this->fresh();
	}
}
void BMenuBar::insertMenu(int index, BMenu* menu)
{
	if (!this->contain(menu))
	{
		this->addChild(menu);
		menu->hide();
		member.items.insert(index, menu);
		member.dirty = true;
		this->fresh();
	}
}
void BMenuBar::removeMenu(BMenu* menu)
{
	if (member.items.remove(menu))
	{
		this->removeChild(menu);
		member.dirty = true;
		this->fresh();
	}
}

void BMenuBar::setSpacing(int spacing)
{
	if (member.spacing != spacing)
	{
		member.spacing = spacing;
		member.dirty = true;
		this->fresh();
	}
}
int BMenuBar::spacing() const
{
	return member.spacing;
}

void BMenuBar::setAlign(Align align)
{
	if (member.align != align)
	{
		member.align = align;
		member.dirty = true;
		this->fresh();
	}
}
Align BMenuBar::align() const
{
	return member.align;
}

BSize BMenuBar::sizeHint() const
{
	return this->shellSize() + member.contentSize;
}

void BMenuBar::styleEvent(const BEvent& changeEvent)
{
	member.dirty = true;
}
void BMenuBar::freshEvent(const BEvent& event)
{
	if (member.dirty)
	{
		member.adjustMenuRects();
		member.dirty = false;
		this->adjust();
	}
}
void BMenuBar::paintEvent(const BEvent& event)
{
	BWidget::paintEvent(event);

	BRect crect = this->clientRect();

	BPainter painter(this);

	for(int i = 0; i < member.items.size(); i++)
	{
		const BRect& rect = member.items[i].rect;
		const BMenu* menu = member.items[i].menu;
		painter.setColor(Color_Background);
		if (member.hoverIndex == i)
		{
			painter.setColor(Color_Background_Hovered);
			if (member.pressed)
				painter.setColor(Color_Background_Pressed);
		}
		painter.fillRect(rect);

		const BString& title = menu->title();
		painter.setColor(Color_Text);
		painter.drawText(rect, title);
	}
}

void BMenuBar::mouseEnterEvent(const BMouseEvent& mouseEvent)
{
	member.hoverIndex = -1;
}
void BMenuBar::mouseLeaveEvent(const BMouseEvent& mouseEvent)
{
	if (member.hoverIndex != -1)
	{
		member.hoverIndex = -1;
		fresh();
	}
}

void BMenuBar::mousePressEvent(const BMouseEvent& mouseEvent)
{
	member.pressed = true;
	this->fresh();
}
void BMenuBar::mouseReleaseEvent(const BMouseEvent& mouseEvent)
{
	member.pressed = false;
	this->fresh();
}
void BMenuBar::mouseMoveEvent(const BMouseEvent& mouseEvent)
{
	int hoverIndex = -1;
	const BPoint& pos = mouseEvent.pos();
	for (int i = 0; i < member.items.size(); i++)
	{
		if (member.items[i].rect.contain(pos))
		{
			hoverIndex = i;
			break;
		}
	}
	if (member.hoverIndex != hoverIndex)
	{
		member.hoverIndex = hoverIndex;
		this->fresh();
	}
}

void BMenuBar::mouseClickEvent(const BMouseEvent& mouseEvent)
{
	if (member.hoverIndex > -1)
	{
		BMenu* menu = member.items[member.hoverIndex].menu;
		if (menu->visible())
		{
			menu->hide();
		}
		else
		{
			BRect& rect = member.items[member.hoverIndex].rect;
			menu->setPos(rect.left(), rect.bottom());
			menu->popup();
		}
		this->fresh();
	}
}
void BMenuBar::mouseDoubleClickEvent(const BMouseEvent& mouseEvent)
{

}
